/*
 * 显示尺寸不可改变 
 * 图片上传前端控件 配合 好运来文件服务器后台使用
 * 作者:37798955@qq.com
 */
//export default 
const vendorUrl = window.URL || window.webkitURL;
navigator.getMedia = navigator.getUserMedia ||
	navagator.webkitGetUserMedia ||
	navigator.mozGetUserMedia ||
	navigator.msGetUserMedia;

class HylUpImg {
	/**
	 * 配置 {图宽, 图高, 水印字}
	 */
	constructor(组件块, 配置, 传成功回调,传失败) {
		let ta = this;
		ta.自增编号 = 0; //给图上传命名时使用
		ta.图片集 = [];
		ta.urls = [];
		ta.上传成功=传成功回调;
		ta.上传失败=传失败;
		ta.当前图片 = null;
		配置 = 配置 || {};
		//console.log(配置)
		ta.上传路径 = 配置.上传路径;
		ta.水印 = 配置.水印字 || "南通好运来";
		ta.拍照状态 = 0;
		ta.组件块 = document.getElementById(组件块);
  let lines = '<div class="w_video">\
	<video></video>\
	<div class="btns">\
		<button class="bt_photo">拍照</button>\
		<button class="bt_cancel">放弃</button>\
	</div>\
</div>\
<!--上传图片块-->\
<div class="w_view">\
	<!--预览拍照效果-->\
	<div class="btns">\
		<span class="title">大小:</span>\
		<span class="title imgsize"></span>\
		<button class="bt_rotate">旋转</button>\
		<button class="bt_save">保存</button>\
		<button class="bt_compress">压缩</button>\
		<button class="bt_close">关闭</button>\
	</div>\
	<canvas></canvas>\
</div>\
<div class="w_img">\
	<!--缩略图列表-->\
</div>\
<div class="w_btn">\
	<!--操作按钮-->\
	<div class="dbt_icon bt_open">\
		<!--上传按钮-->\
		<input type="file" class="file_input" />\
		<span class="tooltiptext">相册</span>\
	</div>\
	<div class="dbt_icon  bt_camera ">\
		<span class="tooltiptext">拍照</span>\
	</div>\
	<div class="dbt_icon  bt_remove">\
		<span class="tooltiptext">删除</span>\
	</div>\
	<div class="dbt_icon  bt_view">\
		<span class="tooltiptext">预览</span>\
	</div>\
	<div class="dbt_icon  bt_send">\
		<span class="tooltiptext">提交</span>\
	</div>\
</div>';
		ta.组件块.innerHTML = lines ;
		ta.拍照区 = ta.组件块.querySelector(".w_video");
		ta.预览区 = ta.组件块.querySelector(".w_view");
		ta.缩略图区 = ta.组件块.querySelector(".w_img");
		ta.按钮区 = ta.组件块.querySelector(".w_btn");
		ta.按钮区.querySelector(".bt_camera").onclick = function() {
			ta.playVideo(); //打开摄像头
		};
		ta.按钮区.querySelector(".bt_remove").onclick = function() {
			ta.removeImg(); //移除
		};
		ta.按钮区.querySelector(".bt_open").onclick = function() {
			ta.按钮区.querySelector(".file_input").click(); //模仿 input点击
		};
		ta.按钮区.querySelector(".file_input").onchange = function(e) {
			ta.readFile(e, this.files); //从相册读取
			this.value = "";
		};
		ta.按钮区.querySelector(".bt_view").onclick = function() {
			ta.viewImg(); //预览
		};
		ta.预览区.querySelector(".btns>.bt_rotate").onclick = function(e) {
			ta.rotateImg(); //旋转
			e.stopImmediatePropagation();
		};
		ta.预览区.querySelector(".btns>.bt_save").onclick = function(e) {
			ta.saveImg(); //保存
		};
		ta.拍照区.querySelector(".btns>.bt_photo").onclick = function(e) {
			ta.takePic();
		};
		ta.预览区.querySelector(".btns>.bt_compress").onclick = function(e) {
			ta.compressImg(); //保存
		};
		ta.按钮区.querySelector(".bt_send").onclick = function(e) {
			ta.upload();
		};
		ta.视频高度 = 720;
		ta.视频宽度 = 1280;
		ta.视频配置 = {
			video: {
				//ideal:最理想的
				width: {
					ideal: ta.视频宽度,
					max: 1920
				},
				height: {
					ideal: ta.视频高度,
					max: 1080
				},
				frameRate: {
					ideal: 10,
					max: 15
				},
				facingMode: "user" //: "environment"
			},
			audio: false
		};
		//console.log(ta.预览区 .getBoundingClientRect().width); 
		ta.video = ta.拍照区.querySelector("video");
		ta.video.onloadedmetadata = function(e) {
			ta.video.play();
			console.log("播放");
		};
		ta.video.onclick = function(e) {
			ta.takePic();
			e.stopImmediatePropagation();
		};
		//如果 面板 没有设置成 overflow:auto ,
		//那么如果实际宽度和高度超出面板,video和图片是无法显示的		
		ta.canvas = ta.预览区.querySelector("canvas");
		ta.预览区.onclick = function(e) {
			ta.预览区.style.display = "none";
		};
		ta.拍照区.onclick = function(e) {
			ta.拍照区.style.display = "none";
		};
		ta.intWH();
		ta.选中图角标 = document.createElement("div");
		ta.选中图角标.className = "selected";
		ta.选中图 = null; //div>img
		//console.log(ta.预览区);
		ta.视频流 = null;


	}
	autoSize(容器宽, 容器高, 实际宽, 实际高) {
		let size = []
		//wrate==hrate
		let wrate = 实际宽 / 容器宽;
		let hrate = 实际高 / 容器高;
		if (wrate == hrate) {
			size = [Math.floor(容器宽), Math.floor(容器高)]
		} else if (wrate > hrate) {
			size = [Math.floor(容器宽), Math.floor(实际高 / wrate)]
		} else {
			size = [Math.floor(实际宽 / hrate), Math.floor(容器高)]
		}
		return size;
	}
	//初始化预览区宽高尺寸
	intWH() {
		let ta = this;
		//console.log(window.innerWidth,window.innerHeight);
		ta.预览区.width = window.innerWidth - 10;
		ta.预览区.height = Math.floor(window.innerHeight * 0.4);
		//console.log(ta.预览区.width,ta.预览区.height)
		window.onresize = function() {
			ta.预览区.width = window.innerWidth - 10;
			ta.预览区.height = Math.floor(window.innerHeight * 0.4);
			//console.log(window.innerWidth,window.innerHeight);
		};
	}
	getCanvas(w, h) {
		let canvas = this.canvas;
		let size = canvas.parentNode.getBoundingClientRect();
		//console	.log(size.width,size.height)	
		//自动适配video的容器尺寸
		let size2 = this.autoSize(size.width * 0.96, size.height * 0.90, w, h);
		canvas.style.width = size2[0] + "px";
		canvas.style.height = size2[1] + "px";
		//console.log(size2, w, h)
		canvas.width = w;
		canvas.height = h;
		return canvas;
	}
	//选中图片
	readFile(e, flist) {
		let ta = this;
		ta.stopVideo();
		//console.log(ta); // 指向类对象 
		//console.log(flist); //选中对象
		//console.log(e.target) //组件对象			
		var file = flist[0]; //获取file对象
		//判断file的类型是不是图片类型。
		if (!/image\/\w+/.test(file.type)) {
			alert("文件必须为图片！");
			return false;
		}
		var reader = new FileReader(); //声明一个FileReader实例
		reader.readAsDataURL(file); //调用readAsDataURL方法来读取选中的图像文件
		//最后在onload事件中，获取到成功读取的文件内容，并以插入一个img节点的方式显示选中的图片
		reader.onload = function(e) {
			//console.log(file); // 指向reader 事件对象
			//console.log(this) //reader对象.数据
		
			ta.addImg(this.result, file);
		}
	}
	//播放摄像头视频
	playVideo() {

		let ta = this;
		//console.log(ta)
		if (!navigator.mediaDevices) return;
		//预览区宽度 高度 不是图片实际宽高
		//ta.video.width = ta.预览宽度;
		//ta.video.height = ta.预览高度;
		navigator.mediaDevices.getUserMedia(ta.视频配置).then(function(stream) {
			//  MediaStreamTrack=stream.getTracks()[1];
			ta.预览区.style.display = "none";
			ta.拍照区.style.display = "block";
			console.log("打开摄像头..")
			ta.视频流 = stream;
			ta.video.srcObject = stream;
			// ta.video.onloadeddata=function(){
			// 	console.log(ta.video.width)
			// }

			//ta.video.src = window.URL.createObjectURL(stream); //老版本
			//vendorUrl.revokeObjectURL(strem);
		}).catch(function(error) {
			console.log(error);
		});
	}

	addText() {
		let canvas = ta.canvas;
		let ctx = canvas.getContext('2d');
		ctx.font = "20px 宋体";
		ctx.fillStyle = "rgba(124, 124, 233, 0.3)";
		ctx.textAlign = 'right';
		//在指定位置绘制文字， 这里指定距离右下角20坐标的地方
		ctx.fillText(ta.水印, canvas.width - 10, canvas.height - 4);
	}
	stopVideo() {
		let ta = this;
		ta.video.src = null;
		if (ta.视频流) {
			ta.视频流.getTracks().forEach(function(track) {
				track.stop();
			});
		}
		ta.拍照区.style.display = "none";
	}
	takePic() {
		let ta = this;
		console.log("拍照..", );
		let canvas = ta.getCanvas(ta.视频宽度, ta.视频高度);
		let ctx = canvas.getContext('2d');
		//ctx.clearRect(0, 0, canvas.width, canvas.height);         // 清除画布
		//解决镜像翻转
		ctx.translate(ta.视频宽度, 0);
		ctx.scale(-1, 1);
		ctx.drawImage(ta.video, 0, 0, ta.视频宽度, ta.视频高度); //
		ta.stopVideo();
		//var fullQuality = canvas.toDataURL("image/jpeg", 1.0);
		// toDataURL  ---  可传入'image/png'---默认, 'image/jpeg'
		let img = canvas.toDataURL("image/jpeg", 0.5); //0.5 压缩比
		//console.log(ctx.getImageData(0, 0, ta.预览宽度, ta.预览高度))
		//这里的img就是得到的图片
		ta.addImg(img);
		//	ta.照片.src = img;
		//console.log('img-----', img);
	}
	//压缩图片
	compressImg(type, 压缩比) {
		let ta = this;
		let imgdata = ta.canvas.toDataURL(type || "image/png", 压缩比 ||
			0.7); //.replace("image/png", "image/octet-stream");
		let img = ta.选中图.getElementsByTagName("img")[0];
	
		img.onload = function(e) {
			img.path= "";
			img.rw=ta.canvas.width;
			img.rh=ta.canvas.height;
			//console.log(img.width, img.height, ta.canvas.width, ta.canvas.height)
		};
		img.src = imgdata;
	}
	//添加缩略图
	/**
	 * @param {Object} imgdata   dataurl 格式
	 * @param {Object} file 预留
	 */
	addImg(imgdata, file) {
		let ta = this;
		var image = new Image(); //这个用来嵌入dom显示成缩略图
		image.src = imgdata;
		var image2 = new Image(); //这个用来读取真实宽高尺寸,不做压缩
		image2.src = imgdata;
		if (file) {
			if (file.path)
				image.path= file.path;
		}
		ta.addImgDiv(image); //放在这里才能确保加载顺序 不能写在onload里面
		//注意：图片的宽高 必须在图片加载完成后显示

		image2.onload = function(e) {
			//console.log(e)
			image.rw=this.width;
			image.rh=this.height;
			//console.log(image.clientWidth, image.offsetWidth, this.width, this.height)

		};
		//console.log(img)
	}
	addImgDiv(img) {
		let ta = this;
		//console.log(imgdata)
		let imgdiv = document.createElement("div");
		imgdiv.appendChild(img);
		//如果从服务器端读取的图片也要转成 base64
	
		imgdiv.onclick = function() {
			//console.log(this);
			ta.选中图 = this;
			let c = ta.缩略图区.children;
			for (let i = 0; i < c.length; i++) {
				let nd = c[i].querySelector(".selected");
				//console.log(nd)
				if (nd)
					c[i].removeChild(nd)
			}
			let d = ta.选中图角标.cloneNode(false);
			this.appendChild(d);
		};
		ta.缩略图区.appendChild(imgdiv);
	}

	//预览图片
	viewImg() {
		let ta = this;
		ta.拍照区.style.display = "none";
		if (ta.选中图) {
			ta.预览区.style.display = "block";
			let img = ta.选中图.getElementsByTagName("img")[0];
			let width =img.rw;
			let height =img.rh;
			ta.预览区.querySelector(".imgsize").innerHtml = "宽度:" + width + ";高度:" + height;
			// ta.预览宽度, ta.预览高度
			//可以用image()获取真实图片宽高				
			let canvas = ta.getCanvas(width, height);
			canvas.step=0;
			let ctx = canvas.getContext('2d');
			//console.log("预览", canvas.width, canvas.height);
			ctx.drawImage(img, 0, 0, width, height);
		}
	}
	//删除图片
	removeImg() {
		let ta = this;
		if (ta.选中图) {
			ta.缩略图区.removeChild(ta.选中图);
			ta.选中图 = null;
		}
	}
	//保存修改好的图片
	saveImg(type) {
		let ta = this;
		//console.log("预览", ta.canvas.width, ta.canvas.height);
		//let imgdata = ta.canvas.toDataURL("image/jpeg"); //0.5 压缩比
		let imgdata = ta.canvas.toDataURL(type || "image/png"); //.replace("image/png", "image/octet-stream");
		let img = ta.选中图.getElementsByTagName("img")[0];
		img.src = imgdata;
		img.onload = function(e) {
			//console.log(e)
			img.path="";
			img.rw=ta.canvas.width;
			img.rh=ta.canvas.height;
			//console.log(img.width, img.height, ta.canvas.width, ta.canvas.height)
		};
	}
	//旋转图片		
	rotateImg() {
		let ta = this;
		if (ta.选中图) {
			let img = ta.选中图.getElementsByTagName("img")[0];
			let width = img.rw;
			let height = img.rh;

			let ctx = ta.canvas.getContext('2d');
			//console.log(ctx)			
			var max_step = 2;
			var step = ta.canvas.step;
			step = step > max_step ? 0 : ++step;

			//console.log(step)
			switch (step) {
				case 0:
					ta.getCanvas(width, height);
					ctx.drawImage(img, 0, 0, width, height);
					break;
				case 1:
					ta.getCanvas(height, width);
					ctx.translate(height, 0);
					ctx.rotate(Math.PI / 2);
					ctx.drawImage(img, 0, 0, width, height);
					break;
				case 2:
					ta.getCanvas(width, height);
					ctx.translate(width, height)
					ctx.rotate(Math.PI);
					ctx.drawImage(img, 0, 0, width, height);
					break;
				case 3:
					ta.getCanvas(height, width);
					ctx.translate(0, width)
					ctx.rotate(Math.PI / 2 * 3);
					ctx.drawImage(img, 0, 0, width, height);
					break;
			}
			ta.canvas.step=step;
			//console.log(ta.canvas.style.width, ta.canvas.style.height,ta.canvas.width, ta.canvas.height);
			//ctx.save();ctx.restore();
		}
	}
	getExtName(type) {
		let i = type.indexOf("/");
		i = i < 0 ? 0 : i + 1;
		return type.substring(i);

	}
	getUrlExtName(filename) {
		let i = type.lastIndexOf(".");
		i = i < 0 ? 0 : i + 1;
		return type.substring(i);

	}
	dataURLtoBlob(dataurl) {
		var arr = dataurl.split(','),
			mime = arr[0].match(/:(.*?);/)[1],
			bstr = atob(arr[1]),
			n = bstr.length,
			u8arr = new Uint8Array(n);
		while (n--) {
			u8arr[n] = bstr.charCodeAt(n);
		}
		return new Blob([u8arr], {
			type: mime
		});
	}

	//上传图片		
	upload(callback) {
		let ta = this;
		//我们规定所有img 只能保存 dataurl 格式数据

		let cc = ta.缩略图区.children;
		if (cc.length == 0) return;
		let fd = new FormData();
		let count = 0;
		for (let i = 0; i < cc.length; i++) {
			let img = cc[i].querySelector("img");
			let blob = ta.dataURLtoBlob(img.src);
			img.mime= blob.type;
			//上传成功的文件名
			let ext = ta.getExtName(blob.type);
			let name = img.name;
			//console.log("name1",name)
			if (name == null|| name == "") { //文件名 
				name = new Date().getTime() + "." + ext;
				img.name=name;
			}
			//console.log("name2",name)
			//console.log(ext, name)
			let path = img.path;
			//path是上传以后的访问路径,缺少path说明需要上传
			if (path == null || path == ""|| path == "null") {
				count++;
				fd.append("image", blob, name);
			}

		}

		if (ta.上传路径 == null) return;
		if (count == 0) return;
		//console.log(ta.上传路径)
		let xhr = new XMLHttpRequest();
		xhr.open("POST", ta.上传路径)
		//进度条
		// xhr.onprogress = function(pe) {
		// 	if (pe.lengthComputable) {
		// 		progressBar.max = pe.total
		// 		progressBar.value = pe.loaded
		// 	}
		// }
		//addEventListener("load", transferComplete);
		//转移完成
		// xhr.onloadend = function(pe) {
		// 	progressBar.value = pe.loaded
		// }
		//onreadystatechange xhr.readyState == 4 && 
		xhr.onload = function(e) {
			//console.log(e);
			if (xhr.status == 200) { //
				let json = JSON.parse(xhr.responseText);
				let msg = JSON.parse(json.MSG);
				//console.log(msg);
			
				let cc = ta.缩略图区.children;
				if (cc.length == 0) return;
				for (let i = 0; i < cc.length; i++) {
					let img = cc[i].querySelector("img");
					let name = img.name;
					for (let j = 0; j < msg.length; j++) {
						let finf = msg[j];
						if (name == finf.oldname) {
							img.path=finf.path;
							img.md5=finf.md5;
						}
					}				
				}
				if (ta.上传成功)
					ta.上传成功(msg)
			}
		}
		xhr.onerror =function(e){
			if (ta.上传失败)
			ta.上传失败(e);
		}
		xhr.send(fd);
	}
	// 下载路径 转 dataurl 文件格式
	urlToDataurl(url, callback, outputFormat) {
		let img = new Image();
		img.crossOrigin = 'Anonymous'; //可以解决跨域问题
		img.onload = function() {
			let canvas = document.createElement('CANVAS');
			let ctx = canvas.getContext('2d');
			let dataURL;
			canvas.height = this.height;
			canvas.width = this.width;
			ctx.drawImage(this, 0, 0);
			dataURL = canvas.toDataURL();
			callback(img, dataURL);
			canvas = null;
		};
		img.src = url;
	}

	/**
	 * 初始加载数据 imgurls
	 * 主要是图像路径 数组格式 ["路径1","路径2","路径3"]
	 */
	loadImgUrls(imgurls) {
		//console.log(imgurls)
		let ta = this;
		if (imgurls == null || imgurls.length == 0) return;
		var gettype = Object.prototype.toString;
		ta.缩略图区.innerHTML = "";
		for (let i = 0; i < imgurls.length; i++) {
			let o = imgurls[i];
			let ty = gettype.call(o);
			let url = null;
			if (ty == "[object String]") {
				url = o;
			} else if (ty == "[object Object]") {
				url = o["url"];
			} else if (ty == "[object Array]") {
				url = o[0];
			}
			ta.urlToDataurl(url, function(img, dataurl) {
				//console.log(url,img, dataurl)
				ta.addImg(dataurl, {
					path: url
				});
			})
			//ta.addImg()
		}
	}
	/**
	 * 获取上传结果
	 * 注意:key 必须加双引号 作为规范的json格式
	 * 默认格式 '{name:"$name",mime:"$mime",md5:"$md5",path:"$path"}'
	 */
	toUrls(结果格式) {
		let ta = this;
		结果格式 = 结果格式 || '{"name":"$name","mime":"$mime","md5":"$md5","path":"$path"}';
		let cc = ta.缩略图区.children;
		if (cc.length == 0) return;
		let list = [];
		for (let i = 0; i < cc.length; i++) {
			let s = 结果格式;
			let img = cc[i].querySelector("img");
			let name = img.name;
			let mime = img.mime;
			let path = img.path;
			let md5 = img.md5;
			s = s.replace("$path", path).replace("$name", name).replace("$mime", mime).replace("$md5", md5);
			//console.log(s)

			list.push(JSON.parse(s))
		}
		//console.log(list)
		return list;
	}
}
export default HylUpImg;